package Statistics;

import java.util.ArrayList;

import Definitions.GraphClass;
import Definitions.NodeClass;
import Global.DirectoryStructureAndSettingsClass;
import Utility.WorkerUtilityClass;



public class clusterCoefficients {
	
	class nodesClusterCoefficientInfoClass
	{
		Double clusterCoefficentOfTheNode;
		Integer degreeOfTheNode;	
		
		nodesClusterCoefficientInfoClass(Double clusterCoefficentOfTheNode, Integer degreeOfTheNode)
		{
			this.clusterCoefficentOfTheNode=clusterCoefficentOfTheNode;
			this.degreeOfTheNode = degreeOfTheNode;		
		}
	}
	
	ArrayList<nodesClusterCoefficientInfoClass> clusterCoefficentsArray;
	DegreeStatistics currentDegreeStatistics;
		
	double clusterCoefficientOfTheGraph = 0;
	
	GraphClass graph;
	int edgeType;
		
	public clusterCoefficients(GraphClass graph, int edgeType, DegreeStatistics currentDegreeStatistics)
	{
		this.graph = graph;
		this.edgeType = edgeType;
		clusterCoefficentsArray = new ArrayList<nodesClusterCoefficientInfoClass>();
		this.currentDegreeStatistics = currentDegreeStatistics;	
	}		
	
	public void calculateClusterCoefficients(GraphClass graph)
	{
		ArrayList <NodeClass> dataSetOfTheGraph = graph.getDataSet();
		int sizeOfTheGraph = dataSetOfTheGraph.size();
		
		double clusteringCoefficientOfTheNode;
		double[] clusteringCoefficentsOfTheNodes = new double[sizeOfTheGraph];			
		
		for(int i=0; i<sizeOfTheGraph; i++)
   	  	{
			clusteringCoefficientOfTheNode = dataSetOfTheGraph.get(i).getClusteringCoefficientOfTheNode(edgeType);
			clusteringCoefficentsOfTheNodes[i] = clusteringCoefficientOfTheNode;
			clusterCoefficentsArray.add(new nodesClusterCoefficientInfoClass(clusteringCoefficientOfTheNode, dataSetOfTheGraph.get(i).getNumberOfNeigbours(edgeType)));			
   		}		
		
		calculateClusterCoefficientOfTheGraph();		
		
		graph.getPropertiesOfTheGraphWithRespectToEdgeType().get(edgeType).clusteringCoefficientRelatedProps.setClusteringCoefficientOfTheNodesAndRelatedParameters(clusteringCoefficentsOfTheNodes, clusterCoefficientOfTheGraph);		
	}
	
	public void print()
	{
		WorkerUtilityClass.printSeperator();
		//printClusterCoefficients();
		//Global.printShorterSeperator();
		//printDegreeBasedClusterCoefficientOfTheGraph();
		//Global.printShorterSeperator();
		printClusterCoefficientOfTheGraph();
		WorkerUtilityClass.printSeperator();	
		
		//Global.printSeperator();		
	}
	
	void printClusterCoefficients()
	{		
		for(int i=0; i<clusterCoefficentsArray.size(); i++)
		{
			if(clusterCoefficentsArray.get(i).degreeOfTheNode==0 || clusterCoefficentsArray.get(i).degreeOfTheNode==1)
			{
				//System.out.println("BU ATILACAK"+i);				
				System.out.println(i+":0");
			}
			else
				System.out.println(i+":"+clusterCoefficentsArray.get(i).clusterCoefficentOfTheNode);
		}
	}
	
	double calculateClusterCoefficientOfTheGraph()
	{
		double sum = 0;
		int numberOfNodesWillBeOmittedFromCalculation = 0;
		int localDegreeOfTheNode;
		Double localClusterCoefficentOfTheNode = 0.0;
		
		for(int i=0; i<clusterCoefficentsArray.size(); i++)
		{
			localDegreeOfTheNode = clusterCoefficentsArray.get(i).degreeOfTheNode;
			if(localDegreeOfTheNode==0 || localDegreeOfTheNode==1)
				numberOfNodesWillBeOmittedFromCalculation++;
			else
			{	
				localClusterCoefficentOfTheNode=clusterCoefficentsArray.get(i).clusterCoefficentOfTheNode;
				sum+=localClusterCoefficentOfTheNode;
			}			
		}
		
		if(numberOfNodesWillBeOmittedFromCalculation < clusterCoefficentsArray.size())
			clusterCoefficientOfTheGraph=sum/(clusterCoefficentsArray.size()-numberOfNodesWillBeOmittedFromCalculation);		
		
		return clusterCoefficientOfTheGraph;		
	}
	
	void printClusterCoefficientOfTheGraph()
	{		
		DirectoryStructureAndSettingsClass.addToLog("clusterCoefficientOfTheGraph:"+clusterCoefficientOfTheGraph);		
	}
}
